package com.etlmaster.executor.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import freemarker.core.CalDateBI;
import freemarker.core.DayOfWeekBI;
import freemarker.core.ExtBuildIn;
import freemarker.template.Template;

/**
 * @author Larry
 * @copyright Larry@etlMaster
 * @since 2017-09-10
 */
public class DpExecutorUtils {

	private static String defaultString;
	private static freemarker.template.Configuration cfg;
	static {
        if( null ==cfg ){
               cfg=new freemarker.template.Configuration();
               //NumberFormat参数
               cfg.setNumberFormat("#.########################################");
       }
	}
	public static String variableSubstitution(final String text, Object data) {
		new ExtBuildIn(new CalDateBI());
		new ExtBuildIn(new DayOfWeekBI());
		defaultString = "NULL";
		StringWriter sw = null;
		String tempStr = "";
		String result = text;
		try {
			// 循环替换变量，直到两次变量替换的结果一致，或者出现异常
			// WARN：可能会出现无限循环的情况，todo，增加替换次数限制
			do {
				sw = new StringWriter();
				tempStr = result;
				Template template = new Template(null, result, null);
				template.process(data, sw);
				result = sw.toString();
			} while (!result.equals(tempStr));
			LogWriter.addLog("DEBUG", "原始文本:{}，替换后:{}", text, sw.toString());
		} catch (Exception e) {
			LogWriter.addLog("DEBUG", "{}", e.getMessage());
			LogWriter.addLog("DEBUG", "请检查({})是否声明",
					getErrorVar(text, (Map<String, Object>) data));

			// return text;
			return defaultString;
		}
		String value = sw.toString();
		if (value.contains(",")) {
			value = value.replaceAll(",", "");
			if (StringUtils.isNumberic(value)) {
				return value;
			}
		}
		return result;
	}

	// fengwen 20150402 获取未声明的变量列表，提醒开发人员
	public static String getErrorVar(String text, Map<String, Object> obj) {
		List<String> ls = new ArrayList<String>();
		try {

			String regex = "(\\$\\{{1})([\\w]*)(\\}{1})";// 只能匹配字符串

			regex = "(\\$\\{{1})(.*?[a-zA-Z\\\\d]+.*?)(\\}{1})";// 能匹配任意字符

			GetErrorVars getVars = new GetErrorVars();
			Map<String, String> map = new HashMap<String, String>();
			Pattern p = Pattern.compile(regex);
			Matcher m = p.matcher(text);

			while (m.find()) {
				String tmp = m.group();
				String varName = m.group(2);
				map.put(varName, tmp);
			}

			for (Map.Entry<String, String> entry : map.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
				if (obj == null) {
					ls.remove(value);
					ls.add(value);
				} else {
					Map<String, String> hash = null;
					if (key.contains(".")) {
						defaultString = getVars.replaceMap(text, key, value,
								hash, obj, ls);

					} else {
						defaultString = getVars.replaceString(text, key, value,
								obj, ls);
					}
				}
				text = defaultString;

			}

			return ls.toString();
		} catch (Exception ex) {

			return ls.toString();
		}
	}

	public static Map<String, Object> addNullVars(String name,
			Map<String, Object> obj) {
		String varName = name.substring(0, name.indexOf("["));

		Map<String, Object> rtn = new HashMap<String, Object>();
		Object instance = obj.get(varName);
		if (instance != null && instance instanceof List) {
			int i = 0;
			for (Object inner : (List) instance) {
				rtn.put(varName + "[" + i + "]", inner);
				i++;
			}
		} else {
			String newVarName = name.substring(0, name.indexOf("."));
			String key = name.substring(name.indexOf(".") + 1);
			Map<String, String> map = new HashMap<String, String>();
			map.put(key, "null");
			rtn.put(newVarName, map);
		}
		rtn.putAll(obj);
		return rtn;
	}

	public static Map<String, Object> parseArgs(String param) {
		if (param.contains("\"")) {
			param = param.replaceAll("\"", "");
		}
		param = replaceMultiSpaceToOneSpace(param);

		String[] paras = param.split(" ");
		Map<String, Object> result = new HashMap<String, Object>();

		result.put("skipStep", "false");// 添加全局的是否忽略步骤标示
		for (int i = 0; i < paras.length; i = i + 2) {
			if ("-t".equalsIgnoreCase(paras[i])) {// 时间参数
				result.put("taskid", paras[i + 1]);
				result.put("jobBatchNo", paras[i + 1]);
			} else if ("-i".equalsIgnoreCase(paras[i])) {// 从第几步开始执行
				result.put("jobStartRunStepId", paras[i + 1]);
				if (!paras[i + 1].equals("0"))
					result.put("skipStep", "true");// 如果不为0则需要值skipStep=true
			} else if ("-e".equalsIgnoreCase(paras[i])) {
				result.put("jobStopStepId", paras[i + 1]);
			}
			result.put(paras[i].substring(1), paras[i + 1]);

		}
		return result;
	}

	public static String replaceMultiSpaceToOneSpace(String s) {
		Pattern pattern = Pattern.compile(" {2,}");
		Matcher matcher = pattern.matcher(s);
		String result = matcher.replaceAll(" ");

		return result.trim();
	}

	public static String getSystemPath() {
		return System.getProperty("user.dir")
				+ System.getProperty("file.separator");
	}

	public static String getLogPath() {

		String logPath = DataCollectionUtils.getProperties("logPath");
		return getSystemPath() + logPath;
	}

	/**
	 * 对当前时间进行格式化操作。eg:'yyyyMMdd'
	 * 
	 * @param formater
	 * @return
	 */
	public static String DateFormater(Date date, String formater) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(formater);
		return dateFormat.format(date);
	}

	// /写批处理文件
	public static File writeToFile(String content, String suff,
			String parentPath, int hashCode) throws IOException {
		String fileName = new Date().getTime() + "_" + hashCode
				+ content.hashCode() + "." + suff;

		
		return writeToFile(content, suff, parentPath, fileName);
	}

	public static File writeToFile(String content, String suff,
			String parentPath, String fileName) throws IOException {

		File f = new File(parentPath, fileName + "." + suff);
		if (f.exists()) {
			f.delete();
		}
		f.createNewFile();
		FileOutputStream fos = new FileOutputStream(f);
		fos.write(content.toString().getBytes("UTF-8"));
		fos.close();
		return f;
	}

	public static String writeJobConfig(String readerPluginConf,
			String writerPluginConf, String parentPath, String suff,
			int hashCode) throws Exception {
		int i = 0;
		File f = new File(parentPath, new Date().getTime() + "_" + i + "_"
				+ hashCode + "_job." + suff);
		while (f.exists()) {
			f = new File(parentPath, new Date().getTime() + "_" + (++i) + "_"
					+ hashCode + "_job." + suff);
		}
		f.createNewFile();
		FileOutputStream out = new FileOutputStream(f);
		String jobid = "<job id=\"" + hashCode + "\">";
		out.write(jobid.getBytes("UTF-8"));
		out.write(System.getProperty("line.separator").getBytes("UTF-8"));
		// 读read配置信息
		FileInputStream in = new FileInputStream(readerPluginConf);
		int c;
		byte buffer[] = new byte[1024];
		while ((c = in.read(buffer)) != -1) {
			for (int n = 0; n < c; n++)
				out.write(buffer[n]);
		}
		in.close();

		// 读writer的配置信息
		in = new FileInputStream(writerPluginConf);
		c = 0;

		while ((c = in.read(buffer)) != -1) {
			for (int n = 0; n < c; n++)
				out.write(buffer[n]);
		}
		in.close();
		out.write(System.getProperty("line.separator").getBytes("UTF-8"));
		out.write("</job>".getBytes("UTF-8"));
		out.close();
		return f.getPath();

	}

}
